﻿'Description:redis帮助类
'Copyright (c) : 通力凯顿（北京）系统集成有限公司
'Writer:Wangjh 
'create Date:20221026
'Rewriter:
'Rewrite Date:
Imports StackExchange.Redis
Imports System.Configuration
Imports System.Threading.Tasks

Public Class RedisHelper
    Private Shared connstr As String = ConfigurationManager.AppSettings("RedisClient")
    Private Shared conn As ConnectionMultiplexer = ConnectionMultiplexer.Connect(connstr)
    Private dbNum As Integer = 1
    Private db As IDatabase = conn.GetDatabase(dbNum)

    Public Sub New(Optional ByVal n As Integer = 1)
        dbNum = n
        db = conn.GetDatabase(dbNum)
    End Sub
    ''' <summary>
    ''' 获取使用的数据库编号
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetDbNum()
        Return dbNum
    End Function

    ''' <summary>
    ''' 获取database
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetDb() As IDatabase
        Return db
    End Function


    ''' <summary>
    ''' 根据key设置过期时间
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="expiry"></param>
    ''' <remarks></remarks>
    Public Sub SetKeyExpiry(ByVal key As String, ByVal expiry As TimeSpan)
        db.KeyExpire(key, expiry)
    End Sub
    ''' <summary>
    ''' 是否存在某个key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ExistsKey(ByVal key As String) As Boolean
        Return db.KeyExists(key)
    End Function
    ''' <summary>
    ''' 删除某个key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DeleteKey(ByVal key As String) As Boolean
        Return db.KeyDelete(key)
    End Function

#Region "String类型操作，异步"
    ''' <summary>
    ''' 设置或更新key的value
    ''' </summary>
    ''' <param name="key">key</param>
    ''' <param name="value">value</param>
    ''' <param name="expiry">过期时间，分钟</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetStringValueAsync(ByVal key As String, ByVal value As String, Optional ByVal expiry As Integer = Nothing) As Task(Of Boolean)
        Return db.StringSetAsync(key, value, TimeSpan.FromMinutes(expiry))
    End Function
#End Region

#Region "String类型操作"
    ''' <summary>
    ''' 设置或更新key的value
    ''' </summary>
    ''' <param name="key">key</param>
    ''' <param name="value">value</param>
    ''' <param name="expiry">过期时间，分钟</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetStringValue(ByVal key As String, ByVal value As String, ByVal expiry As TimeSpan) As Boolean
        Return db.StringSet(key, value, expiry)
    End Function

    ''' <summary>
    ''' 设置或更新key的value
    ''' </summary>
    ''' <param name="key">key</param>
    ''' <param name="value">value</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetStringValue(ByVal key As String, ByVal value As String) As Boolean
        Return db.StringSet(key, value)
    End Function

    ''' <summary>
    ''' 保存多个key value
    ''' </summary>
    ''' <param name="arr"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetStringValue(ByVal arr() As KeyValuePair(Of RedisKey, RedisValue)) As Boolean
        Return db.StringSet(arr)
    End Function

    ''' <summary>
    ''' 获取一个key的值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetStringByKey(ByVal key As String) As RedisValue
        Return db.StringGet(key)
    End Function

    ''' <summary>
    ''' 获取多个key的值
    ''' </summary>
    ''' <param name="keyList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetStringByKey(ByVal keyList As List(Of RedisKey)) As RedisValue()
        Return db.StringGet(keyList.ToArray())
    End Function

    ''' <summary>
    ''' 删除key的值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DeleteStringByKey(ByVal key As String) As Boolean
        Return db.KeyDelete(key)
    End Function

    ''' <summary>
    ''' 删除多个key的值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DeleteStringByKey(ByVal key() As RedisKey) As Boolean
        Return db.KeyDelete(key)
    End Function

    ''' <summary>
    ''' 为计数器数字增长val
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function StringIncrement(ByVal key As String, Optional ByVal val As Double = 1) As Double
        Return db.StringIncrement(key, val)
    End Function

    ''' <summary>
    ''' 为计数器数字减少val
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function StringDecrement(ByVal key As String, Optional ByVal val As Double = 1) As Double
        Return db.StringDecrement(key, val)
    End Function

#End Region

#Region "Hash类型操作"
    ''' <summary>
    ''' 设置或更新hash值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="hashKey"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetHashValue(ByVal key As String, ByVal hashKey As String, ByVal value As String) As Boolean
        Return db.HashSet(key, hashKey, value)
    End Function

    ''' <summary>
    ''' 保存一个集合
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="HashEntryList"></param>
    ''' <remarks></remarks>
    Public Sub SetHashValue(ByVal key As String, ByVal HashEntryList As List(Of HashEntry))
        db.HashSet(key, HashEntryList.ToArray)
    End Sub

    ''' <summary>
    ''' 获取Hash中的单个key的值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="hasFildValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHashValue(ByVal key As String, ByVal hasFildValue As String) As RedisValue
        Return db.HashGet(key, hasFildValue)
    End Function

    ''' <summary>
    ''' 获取hash中的多个key的值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="hasFildValueList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHashValue(ByVal key As String, ByVal hasFildValueList As List(Of RedisValue)) As RedisValue()
        Return db.HashGet(key, hasFildValueList.ToArray())
    End Function

    ''' <summary>
    ''' 获取hashkey所有Redis key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHashAllKeys(ByVal key As String) As RedisValue()
        Return db.HashKeys(key)
    End Function

    ''' <summary>
    ''' 获取hashkey所有Redis Value
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHashAllValues(ByVal key As String) As HashEntry()
        Return db.HashGetAll(key)
    End Function

    ''' <summary>
    ''' 删除hasekey
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="hasFildValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DeleteHash(ByVal key As String, ByVal hasFildValue As String) As Boolean
        Return db.HashDelete(key, hasFildValue)
    End Function

    ''' <summary>
    ''' 是否存在某个hash的key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="hasFildValue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ExistsHash(ByVal key As String, ByVal hasFildValue As String) As Boolean
        Return db.HashExists(key, hasFildValue)
    End Function

#End Region

#Region "List类型操作，双向链表，左进左出，右进右出"
    ''' <summary>
    ''' 从左侧添加list
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PushListLeft(ByVal key As String, ByVal val As RedisValue) As Long
        Return db.ListLeftPush(key, val)
    End Function

    ''' <summary>
    ''' 从左侧添加多个list
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="vals"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PushListLeft(ByVal key As String, ByVal vals() As RedisValue) As Long
        Return db.ListLeftPush(key, vals)
    End Function

    ''' <summary>
    ''' 从右侧添加list
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PushListRight(ByVal key As String, ByVal val As RedisValue) As Long
        Return db.ListRightPush(key, val)
    End Function

    ''' <summary>
    ''' 从右侧添加多个list
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="vals"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PushListRight(ByVal key As String, ByVal vals() As RedisValue) As Long
        Return db.ListRightPush(key, vals)
    End Function

    ''' <summary>
    ''' 从左侧取1个值，并删除
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PopListLeft(ByVal key As String) As RedisValue
        Return db.ListLeftPop(key)
    End Function

    ''' <summary>
    ''' 从右侧取1个值，并删除
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function PopListRight(ByVal key As String) As RedisValue
        Return db.ListRightPop(key)
    End Function

    ''' <summary>
    ''' 获取list所有值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="s"></param>
    ''' <param name="e"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RangeList(ByVal key As String, Optional s As Long = 0, Optional e As Long = -1) As RedisValue()
        Return db.ListRange(key, s, e)
    End Function

    ''' <summary>
    ''' 是否包含某个值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ExistsList(ByVal key As String, ByVal value As String) As Boolean
        Dim values As RedisValue() = db.ListRange(key)

        Return values.Any(Function(n)
                              Return n.ToString() = value
                          End Function)

    End Function


    '下次用再加

#End Region

#Region "Set类型操作，无序不重复集合"

    ''' <summary>
    ''' 添加set数据，根据key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function AddSet(ByVal key As String, ByVal value As RedisValue) As Boolean
        Return db.SetAdd(key, value)
    End Function

    ''' <summary>
    '''  添加多个set数据，根据key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function AddSet(ByVal key As String, ByVal value() As RedisValue) As Boolean
        Return db.SetAdd(key, value)
    End Function

    ''' <summary>
    ''' 求key集合的数量
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSetLength(ByVal key As String) As Long
        Return db.SetLength(key)
    End Function

    ''' <summary>
    ''' 是否包含指定值
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ExistsSet(ByVal key As String, ByVal value As RedisValue) As Boolean
        Return db.SetContains(key, value)
    End Function

    ''' <summary>
    ''' 获取key中的所有值,数据类型要一致，便于存储
    ''' </summary>
    ''' <param name="key"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSetValues(ByVal key As String) As RedisValue()
        Return db.SetMembers(key)
    End Function


    ''' <summary>
    ''' 删除set数据，根据key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RemoveSet(ByVal key As String, ByVal value As RedisValue) As Boolean
        Return db.SetRemove(key, value)
    End Function

    ''' <summary>
    '''  删除多个set数据，根据key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RemoveSet(ByVal key As String, ByVal value() As RedisValue) As Boolean
        If value Is Nothing Then
            Return False
        End If
        If value.Length = 0 Then
            Return False
        End If
        Return db.SetRemove(key, value)
    End Function

    ''' <summary>
    ''' 获取多个key集合的交集
    ''' </summary>
    ''' <param name="keyList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IntersectSet(ByVal keyList() As RedisKey) As RedisValue()
        Return db.SetCombine(SetOperation.Intersect, keyList)
    End Function

    ''' <summary>
    ''' 获取多个key集合的并集(加到一起，去重)
    ''' </summary>
    ''' <param name="keyList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UnionSet(ByVal keyList() As RedisKey) As RedisValue()
        Return db.SetCombine(SetOperation.Union, keyList)
    End Function

    ''' <summary>
    ''' 获取多个key集合的差集(eg:h1,h2,h3,h4和h4,h5,h6两个集合的差集是h5,h6)
    ''' </summary>
    ''' <param name="keyList"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DifferenceSet(ByVal keyList() As RedisKey) As RedisValue()
        Return db.SetCombine(SetOperation.Union, keyList)
    End Function

#End Region

#Region "ZSet类型操作，有序不重复集合"
    ''' <summary>
    ''' 添加value和sequence，根据key
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function AddSortedSet(ByVal key As String, ByVal value As RedisValue, ByVal sequence As Double) As Boolean
        Return db.SortedSetAdd(key, value, sequence)
    End Function

    ''' <summary>
    ''' 自增，在原有score的基础上增加sequence
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="value"></param>
    ''' <param name="saddSequence"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IncrementSortedSet(ByVal key As String, ByVal value As RedisValue, ByVal saddSequence As Double) As Boolean
        Return db.SortedSetIncrement(key, value, saddSequence)
    End Function
#End Region

#Region "分布式锁"
    ''' <summary>
    ''' 锁验证，如果存在锁key并且值是val返回true，如果不存在锁key,设置锁值为val，返回true
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <param name="exp"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function LockTake(ByVal key As RedisKey, ByVal val As RedisValue, ByVal exp As TimeSpan) As Boolean
        Return db.LockTake(key, val, exp)
    End Function
    ''' <summary>
    ''' 释放锁
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="val"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function LockRelease(ByVal key As RedisKey, ByVal val As RedisValue) As Boolean
        Return db.LockRelease(key, val)
    End Function
#End Region
End Class
